home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Cream of the Crop 26
/
Cream of the Crop 26.iso
/
program
/
wdj0697.zip
/
SDKANN.ZIP
/
SOURCE.ZIP
/
CHEKLIST.C
< prev
next >
Wrap
C/C++ Source or Header
|
1997-01-09
|
10KB
|
318 lines
/*****************************************************/
/* cheklist.c */
/* -- Listbox subclass uses user supplied bitmap to */
/* show selection. */
/* -- Make with: */
/* cc -wd -DSTRICT cheklist.c */
/* copy cheklist.dll cheklist.exe */
/*****************************************************/
#define OEMRESOURCE
#include <windows.h>
#include <windowsx.h>
#include <assert.h>
#define max(a,b) ((a)>(b)?(a):(b))
WNDPROC lpfnOrig; /* Original list box wnd proc. */
char szMod[] = "ChekList"; /* Module name. */
char szFuncLo[] = "ChekListLo"; /* Property tags. */
char szFuncHi[] = "ChekListHi";
/* Prototypes. */
void DrawCheck(LPDRAWITEMSTRUCT, LPBITMAP, HBITMAP);
void DrawListItem(LPDRAWITEMSTRUCT);
void DrawString(LPDRAWITEMSTRUCT, LPBITMAP);
HWND HwndGetList(HWND, UINT, UINT);
/* Callbacks. */
LRESULT CALLBACK __export
LwParentProc(HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK __export
LwListProc(HWND, UINT, WPARAM, LPARAM);
int InitCheckList(HINSTANCE hins)
/*****************************************************/
/* -- Initialization entry point. */
/* -- Register the "ChekList" class. */
/*****************************************************/
{
WNDCLASS wcs;
GetClassInfo(NULL, "ListBox", &wcs);
// wcs.style |= CS_GLOBALCLASS;
wcs.lpszClassName = szMod;
wcs.hInstance = hins;
lpfnOrig = wcs.lpfnWndProc;
wcs.lpfnWndProc = LwListProc;
return RegisterClass(&wcs);
}
LRESULT CALLBACK __export LwListProc(HWND hwnd,
UINT wm, WPARAM wParam, LPARAM lParam)
/*****************************************************/
/* Listbox window procedure. */
/*****************************************************/
{
switch (wm)
{
default:
break;
case WM_CREATE: /* Subclass parent to intercept */
{ /* owner draw messages. */
LPCREATESTRUCT lpcrs = (LPCREATESTRUCT)lParam;
HWND hwndParent = lpcrs->hwndParent;
LONG lpfn;
if (GetProp(hwndParent, szFuncLo) == NULL)
{
lpfn = GetWindowLong(hwndParent,
GWL_WNDPROC);
SetProp(hwndParent, szFuncLo,
(HANDLE)LOWORD(lpfn));
SetProp(hwndParent, szFuncHi,
(HANDLE)HIWORD(lpfn));
SubclassWindow(hwndParent, LwParentProc);
}
/* Store bitmap to draw. */
SetProp(hwnd, szMod,
(HANDLE)(LONG)LoadBitmap(NULL, (LPCSTR)OBM_CHECK));
}
break;
case WM_DESTROY:
DeleteObject(RemoveProp(hwnd, szMod));
break;
} /* End switch wm. */
return CallWindowProc(lpfnOrig, hwnd, wm, wParam,
lParam);
}
LRESULT CALLBACK __export LwParentProc(HWND hwnd,
UINT wm, WPARAM wParam, LPARAM lParam)
/*****************************************************/
/* -- Listbox parent subclass procedure. */
/*****************************************************/
{
WNDPROC lpfn;
lpfn = (WNDPROC)MAKELONG(GetProp(hwnd, szFuncLo),
GetProp(hwnd, szFuncHi));
switch (wm)
{
default:
break;
case WM_DESTROY: /* Remove subclasser. */
RemoveProp(hwnd, szFuncLo);
RemoveProp(hwnd, szFuncHi);
SubclassWindow(hwnd, lpfn);
break;
case WM_MEASUREITEM:
{
LPMEASUREITEMSTRUCT lpmis;
HDC hdc;
HWND hwndList;
/* Is it for us? */
lpmis = (LPMEASUREITEMSTRUCT)lParam;
if ((hwndList = HwndGetList(hwnd,
lpmis->CtlType, lpmis->CtlID)) == NULL)
break; /* Nope. */
if ((hdc = GetDC(hwndList)) != NULL)
{
TEXTMETRIC txm;
BITMAP bmp;
HBITMAP hbmp;
/* Leave 2 border thicknesses for caret. */
if ((hbmp = (HBITMAP)GetProp(hwndList, szMod)) !=
NULL)
{
GetObject(hbmp, sizeof bmp, &bmp);
GetTextMetrics(hdc, &txm);
lpmis->itemHeight =
max(txm.tmHeight, bmp.bmHeight) +
2 * GetSystemMetrics(SM_CYBORDER)
- 4 /* ??? ron slop ??? */;
}
ReleaseDC(hwndList, hdc);
}
}
return TRUE;
case WM_DRAWITEM:
{
LPDRAWITEMSTRUCT lpdis;
/* Is it for us? */
lpdis = (LPDRAWITEMSTRUCT)lParam;
if (HwndGetList(hwnd, lpdis->CtlType,
lpdis->CtlID) == NULL)
break; /* Nope. */
DrawListItem(lpdis);
}
return TRUE;
}
return CallWindowProc(lpfn, hwnd, wm, wParam,
lParam);
}
HWND HwndGetList(HWND hwndParent, UINT wType, UINT did)
/*****************************************************/
/* -- Determine if the control is a ChekList. */
/* -- Return window handle if so, else NULL. */
/*****************************************************/
{
HWND hwnd;
char szBuf[sizeof szMod];
if (wType != ODT_LISTBOX ||
(hwnd = GetDlgItem(hwndParent, did)) == NULL)
return NULL;
GetClassName(hwnd, szBuf, sizeof szBuf);
return lstrcmp(szBuf, szMod) == 0 ? hwnd : NULL;
}
void DrawListItem(LPDRAWITEMSTRUCT lpdis)
/*****************************************************/
/* -- Draw an entry in the list box. */
/*****************************************************/
{
HBITMAP hbmp =0;
BITMAP bmp;
if (lpdis->itemAction != ODA_FOCUS)
{
if ((hbmp = (HBITMAP)GetProp(lpdis->hwndItem, szMod)) ==
NULL)
return; /* Out of GDI memory. */
GetObject(hbmp, sizeof bmp, &bmp);
}
if(lpdis->itemAction & ODA_DRAWENTIRE)
{
DrawCheck(lpdis, &bmp, hbmp);
DrawString(lpdis, &bmp);
}
if(lpdis->itemAction & ODA_FOCUS)
{
DrawFocusRect(lpdis->hDC, &lpdis->rcItem);
}
if(lpdis->itemAction & ODA_SELECT)
{
DrawCheck(lpdis, &bmp, hbmp);
DrawString(lpdis, &bmp);
}
#if 0
switch (lpdis->itemAction)
{
default:
assert(FALSE);
break; /* Should assert. */
case ODA_DRAWENTIRE:
DrawCheck(lpdis, &bmp, hbmp);
DrawString(lpdis, &bmp);
if (!(lpdis->itemState & ODS_FOCUS))
break; /* Otherwise, fall through. */
case ODA_FOCUS:
DrawFocusRect(lpdis->hDC, &lpdis->rcItem);
break;
case ODA_SELECT:
DrawCheck(lpdis, &bmp, hbmp);
DrawString(lpdis, &bmp);
break;
}
#endif
}
void DrawString(LPDRAWITEMSTRUCT lpdis, LPBITMAP lpbmp)
/*****************************************************/
/* -- Draw a string in the list box. */
/*****************************************************/
{
int cb;
LPSTR lpsz;
cb = (int)SendMessage(lpdis->hwndItem,
LB_GETTEXTLEN, lpdis->itemID, 0);
if ((lpsz = (LPSTR)GlobalAllocPtr(GHND, cb+1)) == NULL)
return; /* No memory for string. */
SendMessage(lpdis->hwndItem,
LB_GETTEXT, lpdis->itemID, (LONG)lpsz);
COLORREF OldText, OldBk;
if ((lpdis->itemState & ODS_SELECTED))
{
OldText = SetTextColor(lpdis->hDC, GetSysColor(COLOR_HIGHLIGHTTEXT));
OldBk = SetBkColor(lpdis->hDC, GetSysColor(COLOR_HIGHLIGHT));
}
else
{
OldText = SetTextColor(lpdis->hDC, GetSysColor(COLOR_WINDOWTEXT));
OldBk = SetBkColor(lpdis->hDC, GetSysColor(COLOR_WINDOW));
}
int aTabs[2] = { 50, 75 };
TabbedTextOut(lpdis->hDC, /* handle of device context */
lpdis->rcItem.left + (lpbmp->bmWidth * 2),
lpdis->rcItem.top + 1,
lpsz, /* address of text */
lstrlen(lpsz), /* number of characters */
sizeof(aTabs) / sizeof(int), /* number of tabs in array */
aTabs, /* array for tab positions */
0); /* x-coord. for tab expanding */
SetTextColor(lpdis->hDC, OldText);
SetBkColor(lpdis->hDC, OldBk);
GlobalFreePtr(lpsz);
}
void DrawCheck(LPDRAWITEMSTRUCT lpdis, LPBITMAP lpbmp, HBITMAP hbmp)
/*****************************************************/
/* -- Draw a check mark in the list box. */
/*****************************************************/
{
HDC hdcMem;
HBITMAP hbmpSav;
PatBlt(lpdis->hDC, lpdis->rcItem.left,
lpdis->rcItem.top, lpbmp->bmWidth * 2,
lpdis->rcItem.bottom - lpdis->rcItem.top,
WHITENESS); /* Erase. */
if (!(lpdis->itemData & 0x8000))
return; /* Nothing more to draw. */
if ((hdcMem = CreateCompatibleDC(lpdis->hDC)) ==
NULL)
return; /* Out of GDI memory. */
if ((hbmpSav = (HBITMAP)SelectObject(hdcMem, hbmp)) != NULL)
{
BitBlt(lpdis->hDC,
lpdis->rcItem.left + lpbmp->bmWidth / 2,
((lpdis->rcItem.bottom + lpdis->rcItem.top) -
lpbmp->bmHeight) / 2, lpbmp->bmWidth,
lpbmp->bmHeight, hdcMem, 0, 0, SRCCOPY);
SelectObject(hdcMem, hbmpSav);
}
DeleteDC(hdcMem);
}